home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HPAVC
/
HPAVC CD-ROM.iso
/
ZED3DSRC.ZIP
/
XFORMS.H
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-19
|
5KB
|
191 lines
#ifndef __XFORM_H
#define __XFORM_H
#ifdef __cplusplus
extern "C" {
#endif
/* if you want to use fixedpoint for your base type, uncomment what
follows: */
/*#define use_fixed*/
/* if you want to use float for your base type, uncomment what follows: */
#define use_float
#ifdef use_fixed
#include <math.h>
#define REAL fixedpoint
#define mul fixed_mul
#define div fixed_div
#define add(a,b) ((a)+(b))
#define sub(a,b) ((a)-(b))
#define floattoreal(x) ((x)*65536.0)
#define realtofloat(x) ((x)/65536.0)
#define radiantoreal(x) ((x)*(32768.0/M_PI))
#define realtoradian(x) ((x)*(M_PI/32768.0))
#define fixedtoreal(x) (x)
#define realtofixed(x) (x)
/* Normally, you should define "better" functions for better sqrt,
sin and cos using fixed point. For example, orthonormalize
should be optimized for close-to-normal vectors already using
taylor approx. If you need +/- .0002 precision for square root
of numbers between .9604 and 1.0404, you can use sqrt(x)=(1+x)/2 */
#define SQRT(x) floattoreal(sqrt(realtofloat(x)))
#define SIN(x) floattoreal(sin(realtoradian(x)))
#define COS(x) floattoreal(cos(realtoradian(x)))
#elif defined use_float
#include <math.h>
#define REAL float
#define mul(a,b) ((a)*(b))
#define div(a,b) ((a)/(b))
#define add(a,b) ((a)+(b))
#define sub(a,b) ((a)-(b))
#define floattoreal(x) (x)
#define realtofloat(x) (x)
#define radiantoreal(x) ((x)*(.5/M_PI))
#define realtoradian(x) ((x)*2*M_PI)
#define fixedtoreal(x) ((x)/65536.0)
#define realtofixed(x) ((x)*65536l)
#define SQRT sqrt
#define SIN(x) sin(realtoradian(x))
#define COS(x) cos(realtoradian(x))
#else
#error use_fixed or use_float has to be defined in xforms.h
#endif
typedef long fixedpoint;
/* if you want to use fixedpoint, you have to make sure the functions
below (add, sub, mul, div) are implemented for your platform */
fixedpoint fixed_mul(fixedpoint a, fixedpoint b);
fixedpoint fixed_div(fixedpoint a, fixedpoint b);
fixedpoint fixed_add(fixedpoint a, fixedpoint b);
fixedpoint fixed_sub(fixedpoint a, fixedpoint b);
typedef REAL vector[3];
typedef vector matrix[3];
/* For internal reasons, matrices are indexed as matrix[column][row]
instead of the usual matrix[row][column], e.g. matrix is an array
of three _column_ vectors (not rows) */
struct affine_struct
{
matrix m;
vector v;
};
typedef struct affine_struct affine;
/* The affine type defines an affine transformation, that is, multiply
by matrix m then translate by vector v. */
void mat_add(matrix r, matrix a, matrix b);
/* r=a+b */
void mat_sub(matrix r, matrix a, matrix b);
/* r=a-b */
void mat_mul(matrix r, matrix a, matrix b);
/* r=a*b NOTE: r must be different from a and b, though a and b
can be the same */
void mat_mul_vec(vector r, matrix a, vector b);
/* r=a*b NOTE: b has to be different from r */
void mat_mul_scl(matrix r, matrix a, REAL b);
/* multiplies matrix a by scalar b and stores in r */
void vec_mul_scl(vector r, vector a, REAL b);
/* multiplies vector a by a scalar b and stores in r */
void vec_add(vector r, vector a, vector b);
/* r=a+b */
void vec_sub(vector r, vector a, vector b);
/* r=a-b */
REAL vec_dot(vector a, vector b);
/* return a dot b */
void vec_crs(vector r, vector a, vector b);
/* r=a cross b, r HAS to be different from a and b */
void vec_normalize(vector a);
/* normalizes vector a */
void mat_orthonormalize(matrix a);
/* orthonormalizes matrix a (e.g. line vectors will be of unit length
and perpendicular) */
void affine_xform(affine *a, vector i, vector j);
/* transforms vector i into vector j through affine transform a */
void initmatrix(matrix m,
float a00, float a01, float a02,
float a10, float a11, float a12,
float a20, float a21, float a22);
/* stores a00 through a22 in the matrix */
void printmatrix(matrix m);
/* dumps matrix on screen with printf */
void initvector(vector v,
float i, float j, float k);
void printvector(vector v);
void copymatrix(matrix dest, matrix src);
void copyvector(vector dest, vector src);
/* angles when parameter is REAL is from 0 to 1 for a complete circle */
void rotatevectors(vector v1, vector v2,
vector u1, vector u2,
REAL theta);
/* rotates vector v1 and v2 to u1 and u2, which could be references
to the same memory location */
void rotatebase(matrix m, int axis, REAL theta);
/* rotates base in matrix m about the given axis by an angle of theta
Note: you could also make a matrix A of rotation about anything you
want and then use mat_mul(result,A,m) instead of rotatebase(...).
This could save you a few muls and stuff.
axis is either 1, 2 or 3 */
REAL determinant(matrix m);
/* returns the determinant of matrix m. used here mainly for finding
the matrix inverse */
int invert(matrix m, matrix r);
/* inverses matrix m if possible and puts the result in r. returns
0 on success, nonzero on error (matrix has no inverse)
Note that all rotation matrices have an inverse */
int invert_affine(affine *a, affine *r);
/* inverses affine transformation a into r, which can NOT point to the
same object. Return value same as invert function */
#ifdef __cplusplus
}
#endif
#endif